/*
 * Copyright (c) gitee.com/jiandong001.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import HashSet from '@ohos.util.HashSet';
import { ReadableType } from '../bridge/ReadableType';
import { Spacing } from './Spacing'
import { ReadableMap } from '../bridge/ReadableMap'

/** Keys for props that need to be shared across multiple classes. */
export class ViewProps {
  public static readonly VIEW_CLASS_NAME = "RCTView";

  // Layout only (only affect positions of children, causes no drawing)
  // !!! Keep in sync with LAYOUT_ONLY_PROPS below
  public static readonly ALIGN_ITEMS = "alignItems";
  public static readonly ALIGN_SELF = "alignSelf";
  public static readonly ALIGN_CONTENT = "alignContent";
  public static readonly DISPLAY = "display";
  public static readonly BOTTOM = "bottom";
  public static readonly COLLAPSABLE = "collapsable";
  public static readonly FLEX = "flex";
  public static readonly FLEX_GROW = "flexGrow";
  public static readonly FLEX_SHRINK = "flexShrink";
  public static readonly FLEX_BASIS = "flexBasis";
  public static readonly FLEX_DIRECTION = "flexDirection";
  public static readonly FLEX_WRAP = "flexWrap";
  public static readonly HEIGHT = "height";
  public static readonly JUSTIFY_CONTENT = "justifyContent";
  public static readonly LEFT = "left";
  public static readonly MARGIN = "margin";
  public static readonly MARGIN_VERTICAL = "marginVertical";
  public static readonly MARGIN_HORIZONTAL = "marginHorizontal";
  public static readonly MARGIN_LEFT = "marginLeft";
  public static readonly MARGIN_RIGHT = "marginRight";
  public static readonly MARGIN_TOP = "marginTop";
  public static readonly MARGIN_BOTTOM = "marginBottom";
  public static readonly MARGIN_START = "marginStart";
  public static readonly MARGIN_END = "marginEnd";
  public static readonly PADDING = "padding";
  public static readonly PADDING_VERTICAL = "paddingVertical";
  public static readonly PADDING_HORIZONTAL = "paddingHorizontal";
  public static readonly PADDING_LEFT = "paddingLeft";
  public static readonly PADDING_RIGHT = "paddingRight";
  public static readonly PADDING_TOP = "paddingTop";
  public static readonly PADDING_BOTTOM = "paddingBottom";
  public static readonly PADDING_START = "paddingStart";
  public static readonly PADDING_END = "paddingEnd";
  public static readonly POSITION = "position";
  public static readonly RIGHT = "right";
  public static readonly TOP = "top";
  public static readonly WIDTH = "width";
  public static readonly START = "start";
  public static readonly END = "end";
  public static readonly IS_ATTACHMENT = "isAttachment";
  public static readonly AUTO = "auto";
  public static readonly NONE = "none";
  public static readonly BOX_NONE = "box-none";
  public static readonly MIN_WIDTH = "minWidth";
  public static readonly MAX_WIDTH = "maxWidth";
  public static readonly MIN_HEIGHT = "minHeight";
  public static readonly MAX_HEIGHT = "maxHeight";
  public static readonly ASPECT_RATIO = "aspectRatio";

  // Props that sometimes may prevent us from collapsing views
  public static readonly POINTER_EVENTS = "pointerEvents";

  // Props that affect more than just layout
  public static readonly ENABLED = "enabled";
  public static readonly BACKGROUND_COLOR = "backgroundColor";
  public static readonly FOREGROUND_COLOR = "foregroundColor";
  public static readonly COLOR = "color";
  public static readonly FONT_SIZE = "fontSize";
  public static readonly FONT_WEIGHT = "fontWeight";
  public static readonly FONT_STYLE = "fontStyle";
  public static readonly FONT_VARIANT = "fontVariant";
  public static readonly FONT_FAMILY = "fontFamily";
  public static readonly LINE_HEIGHT = "lineHeight";
  public static readonly LETTER_SPACING = "letterSpacing";
  public static readonly NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
  public static readonly NUMBER_OF_LINES = "numberOfLines";
  public static readonly ELLIPSIZE_MODE = "ellipsizeMode";
  public static readonly ADJUSTS_FONT_SIZE_TO_FIT = "adjustsFontSizeToFit";
  public static readonly MINIMUM_FONT_SCALE = "minimumFontScale";
  public static readonly ON = "on";
  public static readonly RESIZE_MODE = "resizeMode";
  public static readonly RESIZE_METHOD = "resizeMethod";
  public static readonly LAYOUT_DIRECTION = "layoutDirection";
  public static readonly TEXT_ALIGN = "textAlign";
  public static readonly TEXT_ALIGN_VERTICAL = "textAlignVertical";
  public static readonly TEXT_DECORATION_LINE = "textDecorationLine";
  public static readonly TEXT_BREAK_STRATEGY = "textBreakStrategy";
  public static readonly OPACITY = "opacity";
  public static readonly OVERFLOW = "overflow";
  public static readonly HIDDEN = "hidden";
  public static readonly SCROLL = "scroll";
  public static readonly VISIBLE = "visible";
  public static readonly ALLOW_FONT_SCALING = "allowFontScaling";
  public static readonly MAX_FONT_SIZE_MULTIPLIER = "maxFontSizeMultiplier";
  public static readonly INCLUDE_FONT_PADDING = "includeFontPadding";
  public static readonly BORDER_WIDTH = "borderWidth";
  public static readonly BORDER_LEFT_WIDTH = "borderLeftWidth";
  public static readonly BORDER_START_WIDTH = "borderStartWidth";
  public static readonly BORDER_END_WIDTH = "borderEndWidth";
  public static readonly BORDER_TOP_WIDTH = "borderTopWidth";
  public static readonly BORDER_RIGHT_WIDTH = "borderRightWidth";
  public static readonly BORDER_BOTTOM_WIDTH = "borderBottomWidth";
  public static readonly BORDER_RADIUS = "borderRadius";
  public static readonly BORDER_TOP_LEFT_RADIUS = "borderTopLeftRadius";
  public static readonly BORDER_TOP_RIGHT_RADIUS = "borderTopRightRadius";
  public static readonly BORDER_BOTTOM_LEFT_RADIUS = "borderBottomLeftRadius";
  public static readonly BORDER_BOTTOM_RIGHT_RADIUS = "borderBottomRightRadius";
  public static readonly BORDER_COLOR = "borderColor";
  public static readonly BORDER_LEFT_COLOR = "borderLeftColor";
  public static readonly BORDER_RIGHT_COLOR = "borderRightColor";
  public static readonly BORDER_TOP_COLOR = "borderTopColor";
  public static readonly BORDER_BOTTOM_COLOR = "borderBottomColor";
  public static readonly BORDER_TOP_START_RADIUS = "borderTopStartRadius";
  public static readonly BORDER_TOP_END_RADIUS = "borderTopEndRadius";
  public static readonly BORDER_BOTTOM_START_RADIUS = "borderBottomStartRadius";
  public static readonly BORDER_BOTTOM_END_RADIUS = "borderBottomEndRadius";
  public static readonly BORDER_START_COLOR = "borderStartColor";
  public static readonly BORDER_END_COLOR = "borderEndColor";
  public static readonly ON_LAYOUT = "onLayout";
  public static readonly TRANSFORM = "transform";
  public static readonly ELEVATION = "elevation";
  public static readonly SHADOW_COLOR = "shadowColor";
  public static readonly Z_INDEX = "zIndex";
  public static readonly RENDER_TO_HARDWARE_TEXTURE = "renderToHardwareTextureAndroid";
  public static readonly ACCESSIBILITY_LABEL = "accessibilityLabel";
  public static readonly ACCESSIBILITY_COLLECTION = "accessibilityCollection";
  public static readonly ACCESSIBILITY_COLLECTION_ITEM = "accessibilityCollectionItem";
  public static readonly ACCESSIBILITY_HINT = "accessibilityHint";
  public static readonly ACCESSIBILITY_LIVE_REGION = "accessibilityLiveRegion";
  public static readonly ACCESSIBILITY_ROLE = "accessibilityRole";
  public static readonly ACCESSIBILITY_STATE = "accessibilityState";
  public static readonly ACCESSIBILITY_ACTIONS = "accessibilityActions";
  public static readonly ACCESSIBILITY_VALUE = "accessibilityValue";
  public static readonly ACCESSIBILITY_LABELLED_BY = "accessibilityLabelledBy";
  public static readonly IMPORTANT_FOR_ACCESSIBILITY = "importantForAccessibility";

  public static readonly TRANSPARENT = 0

  // DEPRECATED
  public static readonly ROTATION = "rotation";
  public static readonly SCALE_X = "scaleX";
  public static readonly SCALE_Y = "scaleY";
  public static readonly TRANSLATE_X = "translateX";
  public static readonly TRANSLATE_Y = "translateY";

  /** Used to locate views in end-to-end (UI) tests. */
  public static readonly TEST_ID = "testID";
  public static readonly NATIVE_ID = "nativeID";
  public static readonly BORDER_SPACING_TYPES: number[] = [
    Spacing.ALL,
    Spacing.START,
    Spacing.END,
    Spacing.TOP,
    Spacing.BOTTOM,
    Spacing.LEFT,
    Spacing.RIGHT
  ];
  public static readonly PADDING_MARGIN_SPACING_TYPES: number[] = [
    Spacing.ALL,
    Spacing.VERTICAL,
    Spacing.HORIZONTAL,
    Spacing.START,
    Spacing.END,
    Spacing.TOP,
    Spacing.BOTTOM,
    Spacing.LEFT,
    Spacing.RIGHT,
  ];
  public static readonly POSITION_SPACING_TYPES: number[] = [
    Spacing.START, Spacing.END, Spacing.TOP, Spacing.BOTTOM
  ];
  private static readonly LAYOUT_ONLY_PROPS: HashSet<string> = ViewProps.buildViewPropsArray();

  private static buildViewPropsArray(): HashSet<string> {
    let props =  new HashSet<string>();
    props.add(ViewProps.ALIGN_SELF);
    props.add(ViewProps.ALIGN_ITEMS);
    props.add(ViewProps.COLLAPSABLE);
    props.add(ViewProps.FLEX);
    props.add(ViewProps.FLEX_BASIS);
    props.add(ViewProps.FLEX_DIRECTION);
    props.add(ViewProps.FLEX_GROW);
    props.add(ViewProps.FLEX_SHRINK);
    props.add(ViewProps.FLEX_WRAP);
    props.add(ViewProps.JUSTIFY_CONTENT);
    props.add(ViewProps.ALIGN_CONTENT);
    props.add(ViewProps.DISPLAY);

    /* position */
    props.add(ViewProps.POSITION);
    props.add(ViewProps.RIGHT);
    props.add(ViewProps.TOP);
    props.add(ViewProps.BOTTOM);
    props.add(ViewProps.LEFT);
    props.add(ViewProps.START);
    props.add(ViewProps.END);

    /* dimensions */
    props.add(ViewProps.WIDTH);
    props.add(ViewProps.HEIGHT);
    props.add(ViewProps.MIN_WIDTH);
    props.add(ViewProps.MAX_WIDTH);
    props.add(ViewProps.MIN_HEIGHT);
    props.add(ViewProps.MAX_HEIGHT);

    /* margins */
    props.add(ViewProps.MARGIN);
    props.add(ViewProps.MARGIN_VERTICAL);
    props.add(ViewProps.MARGIN_HORIZONTAL);
    props.add(ViewProps.MARGIN_LEFT);
    props.add(ViewProps.MARGIN_RIGHT);
    props.add(ViewProps.MARGIN_TOP);
    props.add(ViewProps.MARGIN_BOTTOM);
    props.add(ViewProps.MARGIN_START);
    props.add(ViewProps.MARGIN_END);

    /* paddings */
    props.add(ViewProps.PADDING);
    props.add(ViewProps.PADDING_VERTICAL);
    props.add(ViewProps.PADDING_HORIZONTAL);
    props.add(ViewProps.PADDING_LEFT);
    props.add(ViewProps.PADDING_RIGHT);
    props.add(ViewProps.PADDING_TOP);
    props.add(ViewProps.PADDING_BOTTOM);
    props.add(ViewProps.PADDING_START);
    props.add(ViewProps.PADDING_END);
    return props;
  }

  public static isLayoutOnly(props: ReadableMap, prop: string): boolean {
    if (ViewProps.LAYOUT_ONLY_PROPS.has(prop)) {
      return true;
    } else if (ViewProps.POINTER_EVENTS == prop) {
      let value: string = props.getString(prop);
      return ViewProps.AUTO == value || ViewProps.BOX_NONE == value;
    }

    switch (prop) {
      case ViewProps.OPACITY:
        // null ViewProps.OPACITY behaves like ViewProps.OPACITY = 1
        // Ignore if explicitly set to default ViewProps.OPACITY.
        return props.isNull(ViewProps.OPACITY) || props.getNumber(ViewProps.OPACITY) == 1;
      case ViewProps.BORDER_RADIUS: // Without a background color or border width set, a border won't show.
        if (props.hasKey(ViewProps.BACKGROUND_COLOR)) {
          let valueType: ReadableType = props.getType(ViewProps.BACKGROUND_COLOR);
          if (valueType == ReadableType.Number
          && props.getNumber(ViewProps.BACKGROUND_COLOR) != ViewProps.TRANSPARENT) { //android.graphics.Color color.TRANSPARENT
            return false;
          } else if (valueType != ReadableType.Null) {
            return false;
          }
        }
        if (props.hasKey(ViewProps.BORDER_WIDTH) && !props.isNull(ViewProps.BORDER_WIDTH) && props.getNumber(ViewProps.BORDER_WIDTH) != 0) {
          return false;
        }
        return true;
      case ViewProps.BORDER_LEFT_COLOR:
        return props.getType(ViewProps.BORDER_LEFT_COLOR) == ReadableType.Number
        && props.getNumber(ViewProps.BORDER_LEFT_COLOR) == ViewProps.TRANSPARENT;//android.graphics.Color color.TRANSPARENT
      case ViewProps.BORDER_RIGHT_COLOR:
        return props.getType(ViewProps.BORDER_RIGHT_COLOR) == ReadableType.Number
        && props.getNumber(ViewProps.BORDER_RIGHT_COLOR) == ViewProps.TRANSPARENT;//android.graphics.Color color.TRANSPARENT
      case ViewProps.BORDER_TOP_COLOR:
        return props.getType(ViewProps.BORDER_TOP_COLOR) == ReadableType.Number
        && props.getNumber(ViewProps.BORDER_TOP_COLOR) == ViewProps.TRANSPARENT;//android.graphics.Color color.TRANSPARENT
      case ViewProps.BORDER_BOTTOM_COLOR:
        return props.getType(ViewProps.BORDER_BOTTOM_COLOR) == ReadableType.Number
        && props.getNumber(ViewProps.BORDER_BOTTOM_COLOR) == ViewProps.TRANSPARENT;//android.graphics.Color color.TRANSPARENT
      case ViewProps.BORDER_WIDTH:
        return props.isNull(ViewProps.BORDER_WIDTH) || props.getNumber(ViewProps.BORDER_WIDTH) == 0;
      case ViewProps.BORDER_LEFT_WIDTH:
        return props.isNull(ViewProps.BORDER_LEFT_WIDTH) || props.getNumber(ViewProps.BORDER_LEFT_WIDTH) == 0;
      case ViewProps.BORDER_TOP_WIDTH:
        return props.isNull(ViewProps.BORDER_TOP_WIDTH) || props.getNumber(ViewProps.BORDER_TOP_WIDTH) == 0;
      case ViewProps.BORDER_RIGHT_WIDTH:
        return props.isNull(ViewProps.BORDER_RIGHT_WIDTH) || props.getNumber(ViewProps.BORDER_RIGHT_WIDTH) == 0;
      case ViewProps.BORDER_BOTTOM_WIDTH:
        return props.isNull(ViewProps.BORDER_BOTTOM_WIDTH) || props.getNumber(ViewProps.BORDER_BOTTOM_WIDTH) == 0;
      case ViewProps.OVERFLOW:
        return props.isNull(ViewProps.OVERFLOW) || ViewProps.VISIBLE == props.getString(ViewProps.OVERFLOW);
      default:
        return false;
    }
  }
}
